<template>
  <ContentWrap>
    <!-- 搜索工作栏 -->
    <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"
             label-width="68px">
      <el-form-item label="日期" prop="repDate">
        <el-date-picker v-model="queryParams.repDate" value-format="YYYY-MM-DD HH:mm:ss"
                        type="daterange"
                        start-placeholder="开始日期" end-placeholder="结束日期"
                        :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
                        class="!w-240px" @change="handleQuery"/>
      </el-form-item>
      <el-form-item label="国家" prop="countryCode">
        <el-select v-model="queryParams.countries" placeholder="请选择国家" clearable filterable
                   multiple class="!w-300px">
          <el-option v-for="dict in getDictOptions(DICT_TYPE.COUNTRY_OR_REGION)" :key="dict.value"
                     :label="dict.label" :value="dict.value"/>
        </el-select>
      </el-form-item>
      <el-form-item label="应用" prop="adamId">
        <el-select v-model="queryParams.adamIds" placeholder="请选择应用" clearable multiple
                   class="!w-240px">
          <el-option v-for="dict in getIntDictOptions(DICT_TYPE.ASA_APP_ID)" :key="dict.value"
                     :label="dict.label"
                     :value="dict.value"/>
        </el-select>
      </el-form-item>
      <el-form-item label="维度">
        <el-select v-model="queryParams.dimension" class="!w-240px" clearable multiple
                   @change="handleQuery">
          <el-option label="日期" value="repDate"/>
          <el-option label="国家" value="country"/>
          <el-option label="应用" value="adamId"/>
        </el-select>
      </el-form-item>

      <el-form-item label="显示列">
        <!-- 列显示控制 -->
        <el-select v-model="vColumns" class="!w-180px" multiple placeholder="选择显示的列"
                   @change="saveColumnsToLocalStorage" collapse-tags>
          <el-option label="广告支出" value="adSpend"/>
          <el-option label="销售额" value="ascSales"/>
          <el-option label="订阅所得" value="ascProceeds"/>
          <el-option label="利润CNY" value="profit"/>
          <el-option label="安装次数" value="ascInstalls"/>
          <el-option label="广告安装" value="adInstalls"/>
          <el-option label="自然新增" value="naturallyInstalls"/>
          <el-option label="试订数" value="subTrial"/>
          <el-option label="订阅数" value="subRenewal"/>
          <el-option label="退款数" value="subRefund"/>
          <el-option label="退款销售总额" value="subRefundAmount"/>
          <el-option label="退款所得总额" value="subRefundProceeds"/>
          <el-option label="广告展示" value="adImpressions"/>
          <el-option label="广告点击" value="adTaps"/>
          <el-option label="广告点击率" value="adTtr"/>
          <el-option label="广告转化率" value="adConversionRate"/>
          <el-option label="广告转化费用" value="adCpa"/>
          <el-option label="广告点击付费" value="adCpt"/>
          <el-option label="广告千展费用" value="adCpm"/>
          <el-option label="展示次数" value="ascImpressions"/>
          <el-option label="点击次数" value="ascTaps"/>
          <el-option label="点击率" value="ascTtr"/>
          <el-option label="转化率" value="ascConversionRate"/>
          <el-option label="创建时间" value="createTime"/>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button @click="handleQuery">
          <Icon icon="ep:search" class="mr-5px"/>
          搜索
        </el-button>
        <el-button @click="resetQuery">
          <Icon icon="ep:refresh" class="mr-5px"/>
          重置
        </el-button>
        <el-button type="success" plain @click="handleExport" :loading="exportLoading"
                   v-hasPermi="['asasc:profit-report:export']">
          <Icon icon="ep:download" class="mr-5px"/>
          导出
        </el-button>
      </el-form-item>
    </el-form>
  </ContentWrap>

  <!-- 列表 -->
  <ContentWrap>
    <el-table class="responsive-table" v-loading="loading" :data="list" :stripe="true"
              :show-overflow-tooltip="true"
              :summary-method="getSummaries" show-summary>
      <el-table-column v-if="dimensionColumns.includes('repDate')" label="日期" align="center"
                       :min-width="120"
                       :formatter="dateFormatter2" prop="repDate" sortable/>
      <el-table-column v-if="dimensionColumns.includes('adamId')" label="应用" align="center"
                       prop="adamId"
                       :min-width="140" sortable>
        <template #default="scope">
          <dict-tag :type="DICT_TYPE.ASA_APP_ID" :value="scope.row.adamId"/>
        </template>
      </el-table-column>
      <el-table-column v-if="dimensionColumns.includes('country')" label="国家"
                       :formatter="formatCountryCode"
                       align="center" prop="country" :min-width="150" sortable/>
      <el-table-column v-if="vColumns.includes('adSpend')" label="广告支出" align="center"
                       :min-width="90" prop="adSpend"
                       sortable :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('ascSales')" label="销售额" align="center"
                       prop="ascSales" sortable :min-width="90" :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('ascProceeds')" label="订阅所得" align="center"
                       prop="ascProceeds" :min-width="90" sortable :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('subRefundAmount')" label="退款销售总额"
                       align="center" prop="subRefundAmount"
                       sortable :min-width="90" :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('subRefundProceeds')" label="退款所得总额"
                       align="center"
                       prop="subRefundProceeds" sortable :min-width="90"
                       :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('profit')" label="利润CNY" align="center"
                       prop="profit"
                       :sort-method="profitSortMethod" sortable :min-width="110"
                       :formatter="formatCurrency">
        <template #default="scope">
          <span :style="{
      color: (scope.row.ascProceeds - scope.row.adSpend
        - scope.row.subRefundAmount) > 0 ? 'red' : 'green'
    }">
            {{
              formatCurrency(scope.row, 'profit', scope.row.ascProceeds - scope.row.adSpend
                - scope.row.subRefundAmount)
            }}
          </span>
        </template>
      </el-table-column>
      <el-table-column v-if="vColumns.includes('ascInstalls')" label="总新增" align="center"
                       prop="ascInstalls" sortable
                       :min-width="90"/>
      <el-table-column v-if="vColumns.includes('adInstalls')" label="广告新增" align="center"
                       prop="adInstalls" sortable/>
      <el-table-column v-if="vColumns.includes('naturallyInstalls')" label="自然新增" align="center"
                       prop="naturallyInstalls" sortable/>
      <el-table-column v-if="vColumns.includes('subTrial')" label="试订数" align="center"
                       prop="subTrial" sortable/>
      <el-table-column v-if="vColumns.includes('subRenewal')" label="订阅数" align="center"
                       prop="subRenewal" sortable/>
      <el-table-column v-if="vColumns.includes('subRefund')" label="退款数" align="center"
                       prop="subRefund" sortable/>
      <el-table-column v-if="vColumns.includes('adImpressions')" label="广告展示" align="center"
                       prop="adImpressions"
                       sortable/>
      <el-table-column v-if="vColumns.includes('adTaps')" label="广告点击" align="center"
                       prop="adTaps" sortable/>
      <el-table-column v-if="vColumns.includes('adTtr')" label="广告点击率" align="center"
                       prop="adTtr" sortable
                       :formatter="toPercentage1"/>
      <el-table-column v-if="vColumns.includes('adConversionRate')" label="广告转化率"
                       align="center" prop="adConversionRate"
                       sortable :formatter="toPercentage1"/>
      <el-table-column v-if="vColumns.includes('adCpa')" label="广告转化费用" align="center"
                       prop="adCpa" sortable
                       :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('adCpt')" label="广告点击费用" align="center"
                       prop="adCpt" sortable
                       :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('adCpm')" label="广告千次展示" align="center"
                       prop="adCpm" sortable
                       :formatter="formatCurrency"/>
      <el-table-column v-if="vColumns.includes('ascImpressions')" label="展示次数" align="center"
                       prop="ascImpressions"
                       sortable/>
      <el-table-column v-if="vColumns.includes('ascTaps')" label="点击次数" align="center"
                       prop="ascTaps" sortable/>
      <el-table-column v-if="vColumns.includes('ascTtr')" label="点击率" align="center"
                       prop="ascTtr" sortable
                       :formatter="toPercentage1"/>
      <el-table-column v-if="vColumns.includes('ascConversionRate')" label="转化率" align="center"
                       prop="ascConversionRate"
                       sortable :formatter="toPercentage1"/>
      <el-table-column v-if="vColumns.includes('createTime')" label="创建时间"
                       :formatter="dateFormatter" align="center"
                       prop="createTime" sortable/>
    </el-table>
    <!-- 分页 -->
    <Pagination :total="total" v-model:page="queryParams.pageNo"
                v-model:limit="queryParams.pageSize"
                @pagination="getList"/>
  </ContentWrap>

  <!-- 表单弹窗：添加/修改 -->
  <ProfitReportForm ref="formRef" @success="getList"/>
</template>

<style scoped>
.responsive-table {
  height: 650px;
}

@media (max-width: 768px) and (orientation: portrait) {
  .responsive-table {
    height: 400px;
    /* 移动设备竖屏高度 */
  }
}

@media (max-width: 768px) and (orientation: landscape) {
  .responsive-table {
    height: 300px;
    /* 移动设备横屏高度 */
  }
}
</style>

<script setup lang="ts">
import {DICT_TYPE, getDictOptions, getIntDictOptions} from '@/utils/dict'
import download from '@/utils/download'
import {ProfitReportApi, ProfitReportVO} from '@/api/asasc/profitreport'
import ProfitReportForm from './ProfitReportForm.vue'
import {formatCountryCode, formatCurrency, toPercentage1} from "@/utils";
import {dateFormatter, dateFormatter2} from "@/utils/formatTime";
import {ref} from "vue";

/** 投入产出报告 列表 */
defineOptions({name: 'ProfitReport'})

const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化

// 获取当前日期和过去1天的日期，并格式化为 'yyyy-MM-dd HH:mm:ss'，使用北京时间
const getDefaultDateRange = () => {
  const toBeijingTime = (date) => {
    const offset = date.getTimezoneOffset() * 60000;
    // 28800000ms = 8 hours
    return new Date(date.getTime() + offset + 28800000);
  };

  const formatDateTime = (date) => {
    const y = date.getFullYear();
    const m = String(date.getMonth() + 1).padStart(2, '0');
    const d = String(date.getDate()).padStart(2, '0');
    const h = String(date.getHours()).padStart(2, '0');
    const min = String(date.getMinutes()).padStart(2, '0');
    const s = String(date.getSeconds()).padStart(2, '0');
    return `${y}-${m}-${d} ${h}:${min}:${s}`;
  };

  const endDate = toBeijingTime(new Date());
  const startDate = toBeijingTime(new Date());
  startDate.setDate(startDate.getDate() - 2); // 这里修正为 startDate
  endDate.setDate(endDate.getDate() - 2); // 这里修正为 startDate

  // 设置开始时间为 00:00:00，结束时间为 23:59:59
  startDate.setHours(0, 0, 0, 0);
  endDate.setHours(23, 59, 59, 999);

  console.log(formatDateTime(startDate), formatDateTime(endDate));
  return [formatDateTime(startDate), formatDateTime(endDate)];
};

const loading = ref(true) // 列表的加载中
const list = ref<ProfitReportVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 200,
  orgId: undefined,
  adamIds: undefined,
  repDate: getDefaultDateRange(),
  countries: undefined,
  dimension: undefined
})
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
const vColumns = ref(['adSpend', 'ascProceeds', 'profit', 'ascSales', 'ascInstalls',
  'adInstalls', 'naturallyInstalls', 'subTrial', 'subRenewal', 'subRefund', 'adImpressions',
  'adTaps', 'adTtr', 'adConversionRate', 'adCpa', 'adCpt', 'adCpm'
])
const dimensionColumns = ref(['repDate', 'country', 'adamId'])
// 默认显示的列

/** 查询列表 */
const getList = async () => {
  loading.value = true
  try {
    const data = await ProfitReportApi.getProfitReportPage(queryParams)
    list.value = data.list
    total.value = data.total
  } finally {
    loading.value = false
  }
}

/** 搜索按钮操作 */
const handleQuery = () => {
  if (!queryParams.dimension || queryParams.dimension.length === 0) {
    message.error('维度至少要选一个');
    return;
  }
  if (!queryParams.repDate || queryParams.repDate.length === 0) {
    message.error('日期必须要选');
    return;
  }

  saveDimensionToLocalStorage();

  queryParams.pageNo = 1
  getList()
}

/** 重置按钮操作 */
const resetQuery = () => {
  queryFormRef.value.resetFields()
  handleQuery()
}

/** 添加/修改操作 */
const formRef = ref()

/** 导出按钮操作 */
const handleExport = async () => {
  if (!queryParams.dimension || queryParams.dimension.length === 0) {
    message.error('维度至少要选一个');
    return;
  }
  if (!queryParams.repDate || queryParams.repDate.length === 0) {
    message.error('日期必须要选');
    return;
  }

  saveDimensionToLocalStorage();

  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await ProfitReportApi.exportProfitReport(queryParams)
    download.excel(data, '投入产出报告.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}

// 保存维度设置到 localStorage
const saveDimensionToLocalStorage = () => {
  localStorage.setItem('profitReport.dimension', JSON.stringify(queryParams.dimension));

  dimensionColumns.value = JSON.stringify(queryParams.dimension);
};

// 保存列设置到 localStorage
const saveColumnsToLocalStorage = () => {
  localStorage.setItem('profitReport.vColumns', JSON.stringify(vColumns.value));
};

/** 初始化 **/
onMounted(() => {
  const savedColumns = localStorage.getItem('profitReport.vColumns');
  if (savedColumns) {
    vColumns.value = JSON.parse(savedColumns);
  }

  const savedDimension = localStorage.getItem('profitReport.dimension');
  if (savedDimension) {
    dimensionColumns.value = JSON.parse(savedDimension);
    queryParams.dimension = dimensionColumns.value;
  }

  getList()
})

/** 利润排序方法 */
const profitSortMethod = (a, b) => {
  const profitA = a.ascProceeds - a.adSpend;
  const profitB = b.ascProceeds - b.adSpend;
  return profitA - profitB;
}

/** 求和方法 */
const getSummaries = (param) => {
  const {columns, data} = param;
  const sums = [];
  let totalImpressions = 0;
  let totalTaps = 0;
  let totalInstalls = 0;
  let totalSpend = 0;
  let totalProfit = 0;

  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '总计';
      return;
    }
    const values = data.map(item => Number(item[column.property]));
    if (!values.every(value => isNaN(value))) {
      const sum = values.reduce((prev, curr) => {
        const value = Number(curr);
        if (!isNaN(value)) {
          return prev + curr;
        } else {
          return prev;
        }
      }, 0);

      if (column.property == 'adamId') {
        sums[index] = '';
      } else if (column.property === 'adImpressions') {
        totalImpressions = sum;
        sums[index] = sum;
      } else if (column.property === 'adTaps') {
        totalTaps = sum;
        sums[index] = sum;
      } else if (column.property === 'adInstalls') {
        totalInstalls = sum;
        sums[index] = sum;
      } else if (column.property === 'adSpend' || column.property === 'subRefundAmount'
        || column.property === 'subRefundProceeds') {
        totalSpend = sum;
        sums[index] = `¥${sum.toFixed(2)}`;
      } else if (column.property === 'ascProceeds') {
        sums[index] = `¥${sum.toFixed(2)}`;
      } else if (column.property === 'ascSales') {
        sums[index] = `¥${sum.toFixed(2)}`;
      } else if (column.property === 'adTtr') {
        const ttr = totalImpressions ? (totalTaps / totalImpressions) * 100 : 0;
        sums[index] = `${ttr.toFixed(2)}%`;
      } else if (column.property === 'adConversionRate') {
        const conversionRate = totalTaps ? (totalInstalls / totalTaps) * 100 : 0;
        sums[index] = `${conversionRate.toFixed(2)}%`;
      } else if (column.property === 'adCpa') {
        const avgCpaAmount = totalInstalls ? totalSpend / totalInstalls : 0;
        sums[index] = `¥${avgCpaAmount.toFixed(2)}`;
      } else if (column.property === 'adCpt') {
        const avgCptAmount = totalTaps ? totalSpend / totalTaps : 0;
        sums[index] = `¥${avgCptAmount.toFixed(2)}`;
      } else if (column.property === 'adCpm') {
        const avgCpmAmount = totalImpressions ? (totalSpend / totalImpressions) * 1000 : 0;
        sums[index] = `¥${avgCpmAmount.toFixed(2)}`;
      } else {
        sums[index] = sum;
      }
    } else {
      sums[index] = '';
    }
  });

  // 计算利润总和
  totalProfit = data.reduce((prev, curr) => prev + (curr.ascProceeds - curr.adSpend), 0);
  const profitIndex = columns.findIndex(column => column.label === '利润CNY');
  if (profitIndex !== -1) {
    sums[profitIndex] = `¥${totalProfit.toFixed(2)}`;
  }

  return sums;
}
</script>
